package smlab.image
{
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	/**
	 * 毛玻璃效果背景（有点像flex中Alert后模糊的背景）
	 * Blurs a background (MovieClip or Sprite) behind a transparent window (MovieClip or Sprite).
	 * Based on Pixelfumes AS2 class
	 *
	 * @author Devon O.
	 */
	public class WindowBlur_SM {
		
		private var _background:DisplayObjectContainer;
		private var _window:DisplayObjectContainer;
		
		private var _blurredImageData:BitmapData;
		private var _blurredImage:Bitmap;
		private var _mask:DisplayObjectContainer;
		private var _blurAmount:int;
		
		private var _blur:BlurFilter;
		private var _point:Point = new Point();
		
		/**
		 *
		 * @param	background		MovieClip or Sprite which will be blurred behind window.
		 * @param	window			(Semi) transparent MovieClip or Sprite behind which will be a blurred background.
		 * @param	blurAmount		The amount of blur to apply to background image.
		 *
		 * NOTE: background and window objects *must* be added to display list before instantiating an instance of this class.
		 * TODO: allow multiple window instances with same background.
		 * FLASH BUG: 	If window instance is created programatically, it cannot have filters applied.
		 * 				If window instance is linked to MovieClip in library it CAN have filters applied.
		 */
		public function WindowBlur_SM(background:DisplayObjectContainer, window:DisplayObjectContainer, blurAmount:int = 8 ):void {
			_background = background;
			_window = window;
			_blurAmount = (blurAmount>=0 && blurAmount <= 255) ? blurAmount : 16;
			_blur = new BlurFilter(_blurAmount, _blurAmount, 3);
			
			initBlur();
			initMask();
		}
		
		private function initBlur():void {
			_blurredImageData = new BitmapData(_background.width, _background.height, false);
			_blurredImageData.draw(_background);
			_blurredImageData.applyFilter(_blurredImageData, _blurredImageData.rect, _point, _blur);
			_blurredImage = new Bitmap(_blurredImageData);
			
			_background.addChild(_blurredImage);
		}
		
		private function initMask():void {
			var MaskClass:Class = Object(_window).constructor;
			_mask = new MaskClass();
			_mask.filters = _window.filters;
			_blurredImage.mask = _mask;
			_mask.visible = false;
			
			_window.addChildAt(_mask, 0);
		}
		
		private function update():void {
			_background.removeChild(_blurredImage);
			_blurredImageData.dispose();
			initBlur();
			_blurredImage.mask = _mask;
		}
		
		public function kill():void {
			_background.removeChild(_blurredImage);
			_window.removeChild(_mask);
			
			_blurredImageData.dispose();
			
			_blurredImage = null;
			_blurredImageData = null;
			_mask = null;
			_blur = null;
		}
		
		public function get blurAmount():int { return _blurAmount; }
		
		public function set blurAmount(value:int):void {
			_blurAmount = value;
			_blur.blurX = _blur.blurY = _blurAmount;
			update();
		}
	}
}



/*
使用实例：

package {

import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import com.onebyonedesign.extras.WindowBlur_SM;
import com.onebyonedesign.ui.OBO_ValueSlider;
import com.onebyonedesign.ui.events.ValueSliderEvent;
import flash.geom.Rectangle;
import flash.text.AntiAliasType;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;

public class Main extends Sprite {

// GraphicWindow is MovieClip in .fla library
private var _window:GraphicWindow;
// Background is MovieClip in .fla library
private var _bg:Background;
private var _windowBlur:WindowBlur_SM;
private var _shadow:DropShadowFilter = new DropShadowFilter(2, 90, 0x000000, 1, 2, 2, 1, 3);
private var _dragBounds:Rectangle;

public function Main():void {
// Background is MovieClip in .fla library
_bg = new Background();
addChild(_bg);
init();
}

private function init():void {
initWindow();
initBlur();
initControlPanel();
}

private function initWindow():void {
// GraphicWindow is MovieClip in library
_window = new GraphicWindow();
_window.x = int(stage.stageWidth * .5 - _window.width * .5);
_window.y = int(stage.stageHeight * .5 - _window.height * .5);
_window.filters = [_shadow];

_dragBounds = new Rectangle(0, 0, stage.stageWidth - _window.width, stage.stageHeight - _window.height);

addChild(_window);
_window.addEventListener(MouseEvent.MOUSE_DOWN, pressHandler);
}

private function initBlur():void {
_windowBlur = new WindowBlur_SM(_bg, _window);
}

private function initControlPanel():void {
var cp:Sprite = new Sprite();
cp.graphics.beginFill(0xEAEAEA);
cp.graphics.drawRoundRect(0, 0, 150, 30, 10, 10);
cp.graphics.endFill();
cp.filters = [_shadow];
cp.x = 10;
cp.y = stage.stageHeight - cp.height - 10;

var tf:TextField = new TextField();
var fmt:TextFormat = new TextFormat("_sans", 11);
tf.defaultTextFormat = fmt;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.selectable = false;
tf.mouseEnabled = false;
tf.antiAliasType = AntiAliasType.ADVANCED;
tf.text = "Blur amount:";
tf.x = 5;
tf.y = 5;
cp.addChild(tf);

var blurSlider:OBO_ValueSlider = new OBO_ValueSlider(tf.textWidth, 0, 64, _windowBlur.blurAmount);
blurSlider.x = tf.x + tf.textWidth + 8;
blurSlider.y = 13;
blurSlider.addEventListener(ValueSliderEvent.DRAG, blurChangeHandler);
cp.addChild(blurSlider);

addChild(cp);
}

private function blurChangeHandler(event:ValueSliderEvent):void {
_windowBlur.blurAmount = int(event.value);
}

private function pressHandler(event:MouseEvent):void {
stage.addEventListener(MouseEvent.MOUSE_UP, releaseHandler);
_window.startDrag(false, _dragBounds);
}

private function releaseHandler(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, releaseHandler);
_window.stopDrag();
}
}

}

*/